package com.shm.leetcode;

/**
 * 335. 路径交叉
 * 给你一个整数数组 distance 。
 *
 * 从 X-Y 平面上的点 (0,0) 开始，先向北移动 distance[0] 米，然后向西移动 distance[1] 米，向南移动 distance[2] 米，向东移动 distance[3] 米，持续移动。也就是说，每次移动后你的方位会发生逆时针变化。
 *
 * 判断你所经过的路径是否相交。如果相交，返回 true ；否则，返回 false 。
 *
 *
 *
 * 示例 1：
 *
 *
 * 输入：distance = [2,1,1,2]
 * 输出：true
 * 示例 2：
 *
 *
 * 输入：distance = [1,2,3,4]
 * 输出：false
 * 示例 3：
 *
 *
 * 输入：distance = [1,1,1,1]
 * 输出：true
 *
 *
 * 提示：
 *
 * 1 <= distance.length <= 105
 * 1 <= distance[i] <= 105
 * @author SHM
 */
public class IsSelfCrossing {
    /**
     * 前言
     * 我们先通过枚举各种移动方案来归纳路径交叉的规律。
     *
     * 第 11 次移动和第 22 次移动的情况：
     *
     * 因为这两次移动都是各自方向上的第一次移动，所以这两次移动距离将作为之后移动距离的参考系，但本身没有意义。因此，此时只有 2-12−1 一种情况。
     *
     *
     *
     * 第 33 次移动的情况：
     *
     * 此时一定是 2-12−1，第 33 次移动距离相较于第 11 次移动距离，有三种情况：
     *
     * 3-13−1：第 33 次移动距离小于第 11 次移动距离；
     * 3-23−2：第 33 次移动距离等于第 11 次移动距离；
     * 3-33−3：第 33 次移动距离大于第 11 次移动距离。
     *
     *
     * 第 44 次移动的情况：
     *
     * 当前 33 次移动是 3-13−1 时，第 44 次移动距离相较于第 22 次移动距离，有两种情况：
     *
     * 4-14−1：第 44 次移动距离小于第 22 次移动距离；
     * 4-24−2 和 4-34−3：第 44 次移动距离大于等于第 22 次移动距离相同，出现路径交叉。
     *
     *
     * 根据以上结果，我们发现 3-13−1 具有如下性质：如果在当前的第 ii 次移动之后，存在第 jj 次移动（j > ij>i）的距离大于等于第 j-2j−2 次移动的距离，则会出现路径交叉。另外，我们发现 4-14−1 具有和 3-13−1 相同的性质，于是 4-14−1 等价于 3-13−1；不需要继续讨论 4-14−1 的后续情况。
     *
     * 当前 33 次移动是 3-23−2 时，第 44 次移动距离相较于第 22 次移动距离，有两种情况：
     *
     * 4-44−4：第 44 次移动距离小于第 22 次移动距离；
     * 4-54−5 和 4-64−6：第 44 次移动距离大于等于第 22 次移动距离，出现路径交叉。
     *
     *
     * 根据以上结果，我们发现 3-23−2 具有和 3-13−1 相同的性质，于是 4-44−4 等价于 3-23−2，并间接地等价于 3-13−1；不需要继续讨论 4-44−4 的后续情况。
     *
     * 当前 33 次移动是 3-33−3 时，第 44 次移动距离相较于第 22 次移动距离，有三种情况：
     *
     * 4-74−7：第 44 次移动距离小于第 22 次移动距离；
     * 4-84−8：第 44 次移动距离等于第 22 次移动距离；
     * 4-94−9：第 44 次移动距离大于第 22 次移动距离。
     *
     *
     * 根据以上结果，我们发现 4-74−7 也具有和 3-13−1 相同的性质，于是 4-74−7 等价于 3-13−1；不需要继续讨论 4-74−7 的后续情况。
     *
     * 第 55 次移动的情况：
     *
     * 此时还需要讨论前 44 次移动是 4-84−8 或 4-94−9 的情况。
     *
     * 当前 44 次移动是 4-84−8 时，第 55 次移动距离相较于第 33 次移动距离和第 11 次移动距离，有两种情况：
     *
     * 5-15−1：第 55 次移动距离小于第 33 次移动距离减第 11 次移动距离的差；
     * 5-25−2 和 5-35−3：第 55 次移动距离大于等于第 33 次移动距离减第 11 次移动距离的差，出现路径交叉。
     *
     *
     * 根据以上结果，我们发现 5-15−1 也具有和 3-13−1 相同的性质，于是 5-15−1 等价于 3-13−1；不需要继续讨论 5-15−1 的后续情况。
     *
     * 当前 44 次移动是 4-94−9 时，第 55 次移动距离相较于第 33 次移动距离和第 11 次移动距离，有三种情况：
     *
     * 5-45−4：第 55 次移动距离小于第 33 次移动距离减第 11 次移动距离的差；
     * 5-55−5、5-65−6 和 5-75−7：第 55 次移动距离大于等于第 33 次移动距离减第 11 次移动距离的差，且小于等于第 33 次移动距离；
     * 5-85−8：第 55 次移动距离大于第 33 次移动距离。
     *
     *
     * 根据以上结果，我们发现 5-45−4 也具有和 3-13−1 相同的性质，于是 5-15−1 等价于 3-13−1；不需要继续讨论 5-45−4 的后续情况。
     *
     * 第 66 次移动的情况：
     *
     * 此时还需要讨论前 55 次移动是 5-55−5、5-65−6 或 5-75−7 的情况，以及前 55 次移动是 5-85−8 的情况。
     *
     * 当前 55 次移动是 5-55−5、5-65−6 或 5-75−7 时，我们不妨以 5-65−6 为例，第 66 次移动距离相较于第 44 次移动距离和第 22 次移动距离，有两种情况：
     *
     * 6-16−1：第 66 次移动距离小于第 44 次移动距离减第 22 次移动距离的差；
     * 6-26−2 和 6-36−3：第 66 次移动距离大于等于第 44 次移动距离减第 22 次移动距离的差，出现路径交叉。
     *
     *
     * 根据以上结果，我们发现 6-16−1 也具有和 3-13−1 相同的性质，于是 6-16−1 等价于 3-13−1；不需要继续讨论 6-16−1 的后续情况。
     *
     * 当前 55 次移动是 5-85−8 时，第 66 次移动距离相较于第 44 次移动距离和第 22 次移动距离，有三种情况：
     *
     * 6-46−4：第 66 次移动距离小于第 44 次移动距离减第 22 次移动距离的差；
     * 6-56−5、6-66−6 和 6-76−7：第 66 次移动距离大于等于第 44 次移动距离减第 22 次移动距离的差，且小于等于第 44 次移动距离；
     * 6-86−8：第 66 次移动距离大于第 44 次移动距离。
     *
     *
     * 根据以上结果，我们发现 6-46−4 与 5-45−4 的情况类似，都具有 3-13−1 的性质；6-56−5、6-66−6、6-76−7 与 5-55−5、5-65−6、5-75−7 的情况类似，后续可能出现的情况类似于 6-16−1、6-26−2 和 6-36−3；6-86−8 与 5-85−8 的情况类似，后续可能出现的情况类似 6-46−4、6-56−5、6-66−6、6-76−7 和 6-86−8。
     *
     * 至此，我们已经通过归纳基本得到了路径交叉的规律。
     *
     * 方法一：归纳法（归纳路径交叉的情况）
     * 思路和算法
     *
     * 根据归纳结果，我们发现所有可能的路径交叉的情况只有以下三类：
     *
     *
     *
     * 第 11 类，如上图所示，第 ii 次移动和第 i-3i−3 次移动（包含端点）交叉的情况，例如归纳中的 4-24−2、4-34−3、4-54−5 和 4-64−6。
     *
     * 这种路径交叉需满足以下条件：
     *
     * 第 i-1i−1 次移动距离小于等于第 i-3i−3 次移动距离。
     * 第 ii 次移动距离大于等于第 i-2i−2 次移动距离。
     *
     *
     * 第 22 类，如上图所示，第 55 次移动和第 11 次移动交叉（重叠）的情况，例如归纳中的 5-25−2 和 5-35−3。这类路径交叉的情况实际上是第 33 类路径交叉在边界条件下的一种特殊情况。
     *
     * 这种路径交叉需要满足以下条件：
     *
     * 第 44 次移动距离等于第 22 次移动距离。
     * 第 55 次移动距离大于等于第 33 次移动距离减第 11 次移动距离的差；注意此时第 33 次移动距离一定大于第 11 次移动距离，否则在上一步就已经出现第 11 类路径交叉的情况了。
     *
     *
     * 第 33 类，如上图所示，第 ii 次移动和第 i-5i−5 次移动（包含端点）交叉的情况，例如归纳中的 6-26−2 和 6-36−3。
     *
     * 这种路径交叉需满足以下条件：
     *
     * 第 i-1i−1 次移动距离大于等于第 i-3i−3 次移动距离减第 i-5i−5 次移动距离的差，且小于等于第 i-3i−3 次移动距离；注意此时第 i-3i−3 次移动距离一定大于第 i-5i−5 次移动距离，否则在两步之前就已经出现第 11 类路径交叉的情况了。
     * 第 i-2i−2 次移动距离大于第 i-4i−4 次移动距离；注意此时第 i-2i−2 次移动距离一定不等于第 i-4i−4 次移动距离，否则在上一步就会出现第 33 类路径交叉（或第 22 类路径交叉）的情况了。
     * 第 ii 次移动距离大于等于第 i-2i−2 次移动距离减第 i-4i−4 次移动距离的差。
     *
     * 复杂度分析
     *
     * 时间复杂度：O(n)O(n)，其中 nn 为移动次数。
     *
     * 空间复杂度：O(1)O(1)。
     * 作者：LeetCode-Solution
     * 链接：https://leetcode-cn.com/problems/self-crossing/solution/lu-jing-jiao-cha-by-leetcode-solution-dekx/
     * @param distance
     * @return
     */
    public boolean isSelfCrossing(int[] distance) {
        int n = distance.length;
        for (int i = 3; i < n; i++) {
            //第一种路径交叉的情况
            if (distance[i]>=distance[i-2]&&distance[i-1]<=distance[i-3]){
                return true;
            }

            //第二种路径交叉情况
            if (i==4&&(distance[3]==distance[1]&&distance[4]>=(distance[2]-distance[0]))){
                return true;
            }

            //第三种路径交叉情况
            if (i>=5&&(distance[i-1]>=distance[i-3]-distance[i-5]&&distance[i-3]>=distance[i-1]
                    &&distance[i-2]>distance[i-4]&&distance[i]>=distance[i-2]-distance[i-4])){
                return true;
            }
        }
        return false;
    }
}
